﻿using Microsoft.WindowsAzure.MediaServices.Client;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MediaAdmin.Controllers
{
    [Authorize]
    public partial class AssetController : BaseController
    {

        public ActionResult Index()
        {
            var assets = Context.Assets.ToList();
            var model = ModelMapper.Map<List<IAsset>, List<AssetSummaryShortly>>(assets).OrderBy(x=>x.Created);
            return View(model);
        }


        public ActionResult Details(string id)
        {
            var asset = Context.Assets.Where(x => x.Id == id).SingleOrDefault();
            var model = ModelMapper.Map<IAsset, AssetSummary>(asset);

            var manifest = asset.Files.Where(x => x.Name.EndsWith(".ism")).SingleOrDefault();
            if (manifest != null)
                model.Manifest = manifest.Name;

            return View(model);
        }

        public ActionResult Create()
        {
            return View(new CreateModel());
        }


        [HttpPost]
        public ActionResult Create(CreateModel model)
        {
            try
            {
                var asset = Context.Assets.CreateEmptyAsset(model.AssetName, AssetCreationOptions.None);
                return RedirectToAction("Details", new{ id = asset.Id });
            }
            catch
            {
                return View();
            }
        }

        public ActionResult Edit(string id)
        {
            var model = new EditModel();
            model.Id = id;
            var asset = Context.Assets.Where(x => x.Id == id).SingleOrDefault();
            model.AvailableLocators = ModelMapper.Map<List<ILocator>, List<LocatorSummary>>(asset.Locators.ToList()).OrderBy(x => x.ExpirationDateTime).ToList();
            return View(model);
        }


        [HttpPost]
        public ActionResult Edit(EditModel model)
        {
            try
            {
                var asset = Context.Assets.Where(x => x.Id == model.Id).SingleOrDefault();

                if (model.AvailableLocators != null)
                {
                    foreach (var loc in model.AvailableLocators)
                    {
                        if (!loc.KeepAlive)
                        {
                            var ilocator = asset.Locators.Where(x => x.Id == loc.Id).SingleOrDefault();
                            var accpolicy = ilocator.AccessPolicy;
                            Context.Locators.Revoke(ilocator);
                            Context.AccessPolicies.Delete(accpolicy);
                        }
                    }
                }

                if (model.NewSasReadLocator)
                {
                    IAccessPolicy policy = Context.AccessPolicies.Create("SAS read 1day policy for "+model.Id, TimeSpan.FromDays(1), AccessPermissions.Read);
                    ILocator originLocator = Context.Locators.CreateSasLocator(asset, policy, DateTime.UtcNow.AddMinutes(-5));
                }

                if (model.NewSasWriteLocator)
                {
                    IAccessPolicy policy = Context.AccessPolicies.Create("SAS write 1hour policy for " + model.Id, TimeSpan.FromHours(1), AccessPermissions.Write);
                    ILocator originLocator = Context.Locators.CreateSasLocator(asset, policy, DateTime.UtcNow.AddMinutes(-5));
                }

                if (model.NewStreamingLocator)
                {
                    IAccessPolicy policy = Context.AccessPolicies.Create("Streaming 1day policy for " + model.Id, TimeSpan.FromDays(1), AccessPermissions.Read);
                    ILocator originLocator = Context.Locators.CreateOriginLocator(asset, policy, DateTime.UtcNow.AddMinutes(-5));
                }
                
                return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }

        public ActionResult Delete(string id)
        {
            var asset = Context.Assets.Where(x => x.Id == id).SingleOrDefault();
            var model = new DeleteModel() { Id = asset.Id, Name = asset.Name, Cascade = true };
            return View(model);
        }

        [HttpPost]
        public ActionResult Delete(DeleteModel model)
        {
            var asset = Context.Assets.Where(x => x.Id == model.Id).SingleOrDefault();
            
            if (model.Cascade)
            {
                var locators = asset.Locators.Where(x => x.AssetId == asset.Id);
                foreach (var locator in locators)
                {
                    var accpolicy = locator.AccessPolicy;
                    Context.Locators.Revoke(locator);
                    Context.AccessPolicies.Delete(accpolicy);
                }
            }

            int numberOfContentKeys = asset.ContentKeys.Count();
            for (int i = 0; i < numberOfContentKeys; i++)
            {
                asset.ContentKeys.RemoveAt(i);
            }

            Context.Assets.Delete(asset);
            return RedirectToAction("Index");
        }

        private void UploadFile(string name, bool chunk, byte[] buffer)
        {
            var path = HttpContext.Request.MapPath(string.Format("/Content/{0}", name));

            using (var fs = new FileStream(path, chunk ? FileMode.Append : FileMode.Create))
            {
                fs.Write(buffer, 0, buffer.Length);
            }
        }
    }
}
